package impl

import (
	"context"
	"fmt"
	"net/http"

	"gitee.com/LangHuaHuachihua/blog-go/apps/user"
	"gitee.com/LangHuaHuachihua/blog-go/common"
)

var _ user.Service = &impl{}

// 创建用户func (i *impl) CreateUser(ctx context.Context, in *user.CreateUserRequest) (*user.User, error)
func (i *impl) CreateUser(ctx context.Context, in *user.CreateUserRequest) (*user.User, error) {
	err := in.Validate()
	// logger.L().Debug().Msg(err.Error())
	if err != nil {
		return nil, err
	}
	//构造函数生成实例
	ins := user.NewUser(in)
	ins.HashPassword()
	err = i.db.WithContext(ctx).Save(ins).Error
	// ins, err := i.Save(ctx, ins)
	if err != nil {

		return nil, common.NewResponse(ctx, 0, http.StatusInternalServerError, err.Error())
	}
	return ins, err
}

// 登录
func (i *impl) Login(ctx context.Context, in *user.LoginUserRequest) (*user.Token, error) {
	userinfo, err := i.DescribeUser(ctx, user.NewDescibeUserRequestByName(in.Username))
	if err != nil {
		return nil, err
	}
	// logger.L().Debug().Msgf("user:%s", userinfo)
	err = userinfo.CheckPassWord(in.Password)
	if err != nil {
		return nil, common.NewResponse(ctx, 0, http.StatusUnauthorized, err.Error())
	}
	tk, err := user.NewToken(userinfo.Username)
	if err != nil {
		return nil, common.NewResponse(ctx, 0, http.StatusUnauthorized, err.Error())
	}
	err = i.db.Save(tk).Error
	if err != nil {
		return nil, common.NewResponse(ctx, 0, http.StatusUnauthorized, err.Error())
	}
	return tk, nil
}

// token校验
func (i *impl) ValidateToken(ctx context.Context, in *user.ValidateToken) (*user.Token, error) {
	token, err := user.NewToken("")
	if err != nil {
		return nil, err
	}
	err = i.db.
		WithContext(ctx).
		Model(user.Token{}).
		Where("access_token = ?", in.AccessToken).
		First(token).Error
	if err != nil {
		return nil, err
	}
	return token, nil
}

func (i *impl) DescribeUser(ctx context.Context, in *user.DescibeUserRequest) (*user.User, error) {
	query := i.db.WithContext(ctx).Model(user.User{})
	switch in.DescibeBy {
	case user.DESCIBE_BY_NAME:
		query = query.Where("username = ?", in.DescibeValue)
	case user.DESCIBE_BY_ID:
		query = query.Where("id = ?", in.DescibeValue)
	default:
		return nil, fmt.Errorf("No Args For Query")

	}
	ins := user.NewDefaultUser()

	t := query.First(ins)
	if t.Error != nil {
		return nil, t.Error
	}
	return ins, nil
}
